package vodpush

import (
	"encoding/json"
	"fmt"
	"io"
	"iptv_server/v3/src/settings"
	"iptv_server/v3/v2_src/utils"
	"net/http"
	"net/url"
	"os"
	"path"
	"strings"
)

// let detail = {};
// // sourceKey | vod_play_url ,二选一.
// detail.sourceKey = "homeVideo"; // sourceKey 需要蜘蛛重新获取 vod信息
// detail.vod_id = FROM_PUSHME + bvid_or_aid;// "bilibili_episode:" + title;
// detail.vod_name = title;
// detail.vod_tag = "file";
// detail.vod_pic = pic ? pic : "https://server.lan/file/test.png";
// detail.vod_play_from = "__PUSH_AGENT__";
// // detail.vod_play_url = playlist; // 由 sourceKey 对应的spider 获取!

// let kv = {};
// kv.do = "push"
// kv.prefix = "bilibili_" + aid;
// kv.download_pic = pic ? true : false;
// kv.vod = detail;
// let actionUrl = getTargetBoxUrl();
// return http_post_json(actionUrl, detail);

/*

"{\n" +
"\t\"list\": [{\n" +
"\t\t\"vod_id\": \"137133\",\n" +
"\t\t\"vod_name\": \"磁力测试\",\n" +
"\t\t\"vod_pic\": \"https:/img9.doubanio.com/view/photo/s_ratio_poster/public/p2656327176.webp@User-Agent=com.douban.frodo\",\n" +
"\t\t\"type_name\": \"剧情 / 爱情 / 古装\",\n" +
"\t\t\"vod_year\": \"2022\",\n" +
"\t\t\"vod_area\": \"中国大陆\",\n" +
"\t\t\"vod_remarks\": \"40集全\",\n" +
"\t\t\"vod_actor\": \"刘亦菲\",\n" +
"\t\t\"vod_director\": \"杨阳\",\n" +
"\t\t\"vod_content\": \"　　在钱塘开茶铺的赵盼儿（刘亦菲 饰）惊闻未婚夫、新科探花欧阳旭（徐海乔 饰）要另娶当朝高官之女，不甘命运的她誓要上京讨个公道。在途中她遇到了出自权门但生性正直的皇城司指挥顾千帆（陈晓 饰），并卷入江南一场大案，两人不打不相识从而结缘。赵盼儿凭借智慧解救了被骗婚而惨遭虐待的“江南第一琵琶高手”宋引章（林允 饰）与被苛刻家人逼得离家出走的豪爽厨娘孙三娘（柳岩 饰），三位姐妹从此结伴同行，终抵汴京，见识世间繁华。为了不被另攀高枝的欧阳旭从东京赶走，赵盼儿与宋引章、孙三娘一起历经艰辛，将小小茶坊一步步发展为汴京最大的酒楼，揭露了负心人的真面目，收获了各自的真挚感情和人生感悟，也为无数平凡女子推开了一扇平等救赎之门。\",\n" +
"\t\t\"vod_play_from\": \"磁力测试\",\n" +
"\t\t\"vod_play_url\": \"0$magnet:?xt=urn:btih:9e9358b946c427962533472efdd2efd9e9e38c67&dn=%e9%98%b3%e5%85%89%e7%94%b5%e5%bd%b1www.ygdy8.com.%e7%83%ad%e8%a1%80.2022.BD.1080P.%e9%9f%a9%e8%af%ad%e4%b8%ad%e8%8b%b1%e5%8f%8c%e5%ad%97.mkv&tr=udp%3a%2f%2ftracker.opentrackr.org%3a1337%2fannounce&tr=udp%3a%2f%2fexodus.desync.com%3a6969%2fannounce\"\n" +
"\t}]\n" +
"}";
*/

const (
	default_folderid = 1
	IMAGE_SUFFIX     = ".png"
	JSON_SUFFIX      = ".json"

	SHOW_SUFFIX = ".ok"
)

func GetShowSuffix() string {
	return JSON_SUFFIX + SHOW_SUFFIX
}

var (
	DEFAULT_FOLDERID = fmt.Sprintf("%d", default_folderid)
	PUSHED_BASE_DIR  = path.Join(settings.Dir_StaticFile, settings.Dir_Videos, settings.Dir_others_store, "pushed")
	// settings.SiteDomain,
	PUSHED_BASE_URL = path.Join(settings.UrlPath_StaticFile, settings.Dir_Videos, settings.Dir_others_store, "pushed")
)

type vod struct {
	Vod_id             string `json:"vod_id"`
	Vod_id_pre         string `json:"vod_id_pre"`
	Vod_name           string `json:"vod_name"`
	Vod_tag            string `json:"vod_tag"`
	Vod_pic            string `json:"vod_pic"`
	Vod_pic_pre        string `json:"vod_pic_pre"`
	Vod_play_from      string `json:"vod_play_from"`
	Vod_play_url       string `json:"vod_play_url"`
	Vod_play_url_fetch string `json:"vod_play_url_fetch"`

	//可选.
	Type_name    string `json:"type_name"`
	Vod_year     string `json:"vod_year"`
	Vod_area     string `json:"vod_area"`
	Vod_remarks  string `json:"vod_remarks"`
	Vod_actor    string `json:"vod_actor"`
	Vod_director string `json:"vod_director"`
	Vod_content  string `json:"vod_content"`
}

// func (v *vod) MarshalJSON() ([]byte, error) {
// 	// MarshalJSON() ([]byte, error)
// 	return json.Marshal(v)
// }

type pusher struct {
	// site               string //`json:"-"` // http://xxxxx
	// siteRootPath       string //`json:"-"` // /a/b/c
	parentUrl string //`json:"-"` // /d/e/f

	Do                 string `json:"do"`
	Vod                vod    `json:"vod"`
	SourceKey          string `json:"sourceKey"`
	Fullscreen         bool   `json:"fullscreen"`
	Prefix             string `json:"prefix"`
	NeedDownload_pic   bool   `json:"download_pic"`
	NeedDownload_video bool   `json:"download_video"`

	show bool `json:"-"`
}

func (pu *pusher) Unmarshal(bs []byte) error {
	err := json.Unmarshal(bs, pu)
	return err
}

// show : show for HomeActivity.
//
//	Home2Activity显示全部.
//	HomeActivity只显示 show==true的
func (pu *pusher) Marshal() ([]byte, error) {
	j := pu.getFilePath(DEFAULT_FOLDERID, JSON_SUFFIX)
	// 处理 vod_id,
	if len(pu.Vod.Vod_id_pre) == 0 {
		pu.Vod.Vod_id_pre = pu.Vod.Vod_id
	}
	pu.Vod.Vod_id = pu.getUrl(DEFAULT_FOLDERID, JSON_SUFFIX)
	// pu.Vod.Vod_play_url_fetch = "/api/onlinevod/from_bili/" + aid

	if bs, err := json.Marshal(pu.Vod); err == nil {
		_ = os.WriteFile(pu.getFilePath(DEFAULT_FOLDERID, JSON_SUFFIX), bs, 0644)
	}

	bs, err := json.Marshal(pu)
	// save json data
	if err != nil {
		os.WriteFile(j, bs, 0644) // 不检查错误

		if pu.show {
			os.Create(pu.getFilePath(DEFAULT_FOLDERID, GetShowSuffix()))
		}
	}
	// if err == nil && len(bs) > 10 { // 大概是不需要了! !! 这里包裹也是 包裹 vod!!!
	// 	bs = append(bs, []byte(`{"list":[`)...)
	// 	bs = append(bs, []byte(`]}`)...)
	// }
	return bs, err
}

func download(path string, url string) error {
	// TODO: check exist!
	if _, err := os.Stat(path); !os.IsNotExist(err) {
		// file exist : 不覆盖
		return nil
	}

	resp, err := http.Get(url)
	if err != nil {
		fmt.Printf("err: %v\n", err)
		return err
	}

	file, err := os.Create(path)
	if err != nil {
		fmt.Printf("err: %v\n", err)
		return err
	}

	defer resp.Body.Close()
	defer file.Close()

	_, err = io.Copy(file, resp.Body)
	return err
}

func VodToDir2(name string, isDel bool) bool {
	name = strings.Trim(name, "/")
	if strings.Contains(name, "/") {
		// name 不可以包含 /  ../ 这些路径
		//   如果不检查: 会很危险, 可以删除其他文件!!
		return false
	}

	if len(name) == 0 {
		return false
	}

	isExist := func(p string) bool {
		_, err := os.Stat(p)
		return !os.IsNotExist(err)
	}

	join := func(n, suffix string) string {
		p := path.Join(PUSHED_BASE_DIR, n, name+suffix)
		return p
	}

	f_json := join(DEFAULT_FOLDERID, JSON_SUFFIX)
	fmt.Printf("f_json: %v\n", f_json)
	if !isExist(f_json) {
		// 必须先存在 vod 才可以创建show!
		return false
	}

	deleteFile := func(p string) error {
		if _, err := os.Stat(p); !os.IsNotExist(err) {
			return os.Remove(p)
		} else {
			return err
		}
	}

	createFile := func(f string) error {
		_, err := os.Create(f)
		return err

	}

	f := join(DEFAULT_FOLDERID, GetShowSuffix())
	fmt.Printf("f: %v\n", f)
	if isDel {
		if deleteFile(f) == nil {
			return true
		}
	} else {
		if createFile(f) == nil {
			return true
		}
	}
	return false

	// //json
	// //jpg
	// f1_image := join(DEFAULT_FOLDERID, IMAGE_SUFFIX)
	// f1_json := join(DEFAULT_FOLDERID, JSON_SUFFIX)
	// if isDel {
	// 	deleteFile(f1_json)
	// 	deleteFile(f1_image)
	// } else {
	// 	f2_image := join(id, IMAGE_SUFFIX)
	// 	f2_json := join(id, JSON_SUFFIX)
	// 	copyFile(f2_image, f1_image)
	// 	copyFile(f2_json, f1_json)
	// }

}

func (pu *pusher) getFilePath(n, suffix string) string {
	// /videos/others_store/pushed/1/
	// http:// /files/videos/others_store/pushed/1/
	newfilename := fmt.Sprintf("%s%s", pu.Prefix, suffix)
	// p := path.Join(settings.Dir_StaticFile, pu.parentUrl, newfilename)
	p := path.Join(PUSHED_BASE_DIR, n, newfilename)
	return p
}

func (pu *pusher) getUrl(n, suffix string) string {
	newfilename := fmt.Sprintf("%s%s", pu.Prefix, suffix)
	url, _ := url.JoinPath(PUSHED_BASE_URL, n, newfilename)
	return url
}

func (pu *pusher) DownloadPic() error {
	// if !pu.NeedDownload_pic || len(pu.Vod.Vod_pic) == 0 || !utils.IsHttpUrl(pu.Vod.Vod_pic) {
	if len(pu.Vod.Vod_pic) == 0 || !utils.IsHttpUrl(pu.Vod.Vod_pic) {
		return nil
	}

	// newfilename := fmt.Sprintf("%s%s", pu.Prefix, suffix)
	// // /data/files  more_and_more  Name
	// // p := path.Join(pu.siteRootPath, pu.parentUrl, newfilename)
	// p := path.Join(settings.Dir_StaticFile, pu.parentUrl, newfilename)
	p := pu.getFilePath(DEFAULT_FOLDERID, IMAGE_SUFFIX)
	if len(pu.Vod.Vod_pic_pre) == 0 {
		pu.Vod.Vod_pic_pre = pu.Vod.Vod_pic
	}
	pu.Vod.Vod_pic = pu.getUrl(DEFAULT_FOLDERID, IMAGE_SUFFIX)
	err := download(p, pu.Vod.Vod_pic_pre)
	// if err == nil { // && utils.IsHttpUrl(pu.site) {
	// 	// pu.Vod.Vod_pic = fmt.Sprintf("%s/%s/%s", pu.site, pu.parentUrl, newfilename)
	// 	// site http://xxxx:19999
	// 	//    /files
	// 	//    more_and_more
	// 	// pu.Vod.Vod_pic, _ = url.JoinPath(settings.SiteDomain, settings.UrlPath_StaticFile, pu.parentUrl, newfilename)
	// 	pu.Vod.Vod_pic = pu.getUrl(suffix)
	// 	// pu.Vod.Vod_pic = fmt.Sprintf("%s/%s/%s", settings.SiteDomain, settings.UrlPath_StaticFile, pu.parentUrl, newfilename)
	// }
	return err
}

// func (pu *pusher) Download_video() (string, error) {
// 	//TODO : Vod_play_url
// 	if !pu.NeedDownload_video || len(pu.Vod.Vod_play_url) == 0 || utils.IsHttpUrl("") {
// 		// TODO: 需要解析 Vod_play_url. split, and get real url
// 		return "", nil
// 	}
// 	return pu.download("", ".mp4", pu.siteRootPath+"/"+pu.parentUrl)
// }

// func New(site, siteRootPath, parentUrl string) *pusher {
func New(parentUrl string) *pusher {

	// vp := vodpush.New("http://v3.tv.server.lan:19999", "/data/files", "more_and_more")
	pu := &pusher{
		// site:         strings.TrimRight(site, "/"),
		// siteRootPath: strings.TrimRight(siteRootPath, "/"),
		parentUrl:  strings.Trim(parentUrl, "/"),
		Fullscreen: true,
		Vod: vod{
			Type_name: "push",
		},
	}

	return pu
}
